/*
//              INTEL CORPORATION PROPRIETARY INFORMATION
//  This software is supplied under the terms of a license  agreement or
//  nondisclosure agreement with Intel Corporation and may not be copied
//  or disclosed except in  accordance  with the terms of that agreement.
//      Copyright (c) 2006-2007 Intel Corporation. All Rights Reserved.
//
//
*/
#include "umc_defs.h"
#if defined (UMC_ENABLE_DVHD_VIDEO_DECODER)

#include "umc_dv100_decoder.h"
#include <ippvc.h>

namespace UMC
{

static Ipp32s MacroBlockWidth = 16;
static Ipp32s MacroBlockHeight = 16;
static Ipp32s MacroBlockHalfHeight = 8;
static Ipp32s SuperBlockWidth = 9 * MacroBlockWidth;

static
void InitializeOffsets(Ipp8u **pDestinations,
                       Ipp8u *pDestImage,
                       size_t nDestPitch,
                       Ipp32s nChannelNum,
                       Ipp32s nDIFSeqNum,
                       Ipp32s nVideoSegmentNum,
                       Ipp32s nBottomMBWidth = 32)
{
    Ipp32s MBNum;
    Ipp32s s = nDIFSeqNum / 5;
    Ipp32s x = nDIFSeqNum % 5;
    Ipp32s t = (nVideoSegmentNum + 27*x) % 5;
    Ipp32s k = (nVideoSegmentNum + 27*x) / 5;
    Ipp32s h = nChannelNum;
    Ipp32s SuperBlockVertOrder[]=
    {
        (4*h + s + 2*t + 2) % 10, // a
        (4*h + s + 2*t + 6) % 10, // b
        (4*h + s + 2*t + 8) % 10, // c
        (4*h + s + 2*t + 0) % 10, // d
        (4*h + s + 2*t + 4) % 10  // e
    };
    Ipp32s SuperBlockHorzOrder[] = {2, 1, 3, 0, 4};
    Ipp32s BytesPerPixel = 2;

    for(MBNum = 0; MBNum<5; MBNum++)
    {
        Ipp32s Row = k/9;
        Ipp32s Col = k%9;
        Ipp32s MBVertOrder =  h/2 + SuperBlockVertOrder[MBNum]*6 + Row*2;
        Ipp32s MBHorzOrder = (h%2 + SuperBlockHorzOrder[MBNum]*2 ) * 9 + Col;
        if( MBHorzOrder < 80 )
        {
            pDestinations[2*MBNum] = pDestImage +
                               MacroBlockHeight * 4  * nDestPitch +    //skip 4 macro blocks from A0-A7
                               MBVertOrder * MacroBlockHeight * nDestPitch +
                               MBHorzOrder * MacroBlockWidth * BytesPerPixel;

            pDestinations[2*MBNum + 1] = pDestinations[2*MBNum] + nDestPitch * MacroBlockHalfHeight;
        }
        else if ( MBVertOrder < 4 * 8 )
        {
            //A0-A7
            Ipp32s A = MBVertOrder / 4;
            pDestinations[2*MBNum] = pDestImage +
                                   (MBVertOrder % 4) * MacroBlockHeight * nDestPitch +
                                   (A * 10 + (MBHorzOrder - 80) ) * MacroBlockWidth * BytesPerPixel;

            pDestinations[2*MBNum+1] = pDestinations[2*MBNum] + nDestPitch * MacroBlockHalfHeight;
        }
        else if ( MBVertOrder < 4 * 8  + 3*8)
        {
            //A8-A15
            Ipp32s A = (MBVertOrder - 4 * 8) / 3;
            pDestinations[2*MBNum] = pDestImage +
                                   (60 + 4) * MacroBlockHeight * nDestPitch + //Skip A0-A7 and main part of the frame
                                   ( (MBVertOrder - 4*8) % 3) * MacroBlockHeight * nDestPitch +
                                   (A * 10 + (MBHorzOrder - 80) ) * MacroBlockWidth * BytesPerPixel;

            pDestinations[2*MBNum+1] = pDestinations[2*MBNum] + nDestPitch * MacroBlockHalfHeight;
        }
        else
        {
            //B16
            pDestinations[2*MBNum] = pDestImage +
                                   (60 + 4 + 3) * MacroBlockHeight * nDestPitch + //Skip A0-A7, main part of the frame and A8-A15
                                   ( (MBVertOrder - (4*8 + 3*8) ) * 10 + (MBHorzOrder - 80) ) * nBottomMBWidth * BytesPerPixel;

            pDestinations[2*MBNum+1] = pDestinations[2*MBNum] + MacroBlockWidth * BytesPerPixel;
        }
    }
}

void DV100VideoDecoder::Store_System1080_60i_Segment(Ipp16s* pDecodedVideoSegment, Ipp32s nChannelNum, Ipp32s nDIFSeqNum, Ipp32s nVideoSegmentNum)
{
    Ipp8u *pDestinations[10];
    // reset pointers
    if (0 == m_shortCutModeFlag)
    {
        InitializeOffsets(pDestinations, m_pDestination, m_nDestPitch, nChannelNum, nDIFSeqNum, nVideoSegmentNum);
        ippiYCrCb422ToYCbCr422_10HalvesMB16x8_DV100_16s8u_P3C2R(pDecodedVideoSegment, pDestinations, m_nDestPitch);
    }
    else if (1 == m_shortCutModeFlag)
    {
        MacroBlockWidth = 8;
        MacroBlockHeight = 8;
        MacroBlockHalfHeight = 4;
        SuperBlockWidth = 9 * MacroBlockWidth;
        InitializeOffsets(pDestinations, m_pDestination, m_nDestPitch, nChannelNum, nDIFSeqNum, nVideoSegmentNum, 16);
        QuarterResolutionStoreYCrCb422ToYCbCr422_DV100_16s8u_P3C2R(pDecodedVideoSegment, pDestinations, m_nDestPitch);
    }
    else if (2 == m_shortCutModeFlag)
    {
        MacroBlockWidth = 4;
        MacroBlockHeight = 4;
        MacroBlockHalfHeight = 2;
        SuperBlockWidth = 9 * MacroBlockWidth;
        InitializeOffsets(pDestinations, m_pDestination, m_nDestPitch, nChannelNum, nDIFSeqNum, nVideoSegmentNum, 8);
        Resolution8x8To4x4To2x2StoreYCrCb422ToYCbCr422_DV100_16s8u_P3C2R(pDecodedVideoSegment, pDestinations, m_nDestPitch);
    }
    else if (3 == m_shortCutModeFlag)
    {
        MacroBlockWidth = 2;
        MacroBlockHeight = 2;
        MacroBlockHalfHeight = 1;
        SuperBlockWidth = 9 * MacroBlockWidth;
        InitializeOffsets(pDestinations, m_pDestination, m_nDestPitch, nChannelNum, nDIFSeqNum, nVideoSegmentNum, 4);
        DCOnlyStoreYCrCb422ToYCbCr422_DV100_16s8u_P3C2R(pDecodedVideoSegment, pDestinations/*, m_nDestPitch*/);
    }
    else if (4 == m_shortCutModeFlag)
    {
        MacroBlockWidth = 16;
        MacroBlockHeight = 8;
        MacroBlockHalfHeight = 4;
        SuperBlockWidth = 9 * MacroBlockWidth;
        InitializeOffsets(pDestinations, m_pDestination, m_nDestPitch, nChannelNum, nDIFSeqNum, nVideoSegmentNum);
        Resolution8x8To8x4StoreYCrCb422ToYCbCr422_DV100_16s8u_P3C2R(pDecodedVideoSegment, pDestinations, m_nDestPitch);
    }
    else if (5 == m_shortCutModeFlag)
    {
        MacroBlockWidth = 16;
        MacroBlockHeight = 4;
        MacroBlockHalfHeight = 2;
        SuperBlockWidth = 9 * MacroBlockWidth;
        InitializeOffsets(pDestinations, m_pDestination, m_nDestPitch, nChannelNum, nDIFSeqNum, nVideoSegmentNum);
        Resolution8x8To8x2StoreYCrCb422ToYCbCr422_DV100_16s8u_P3C2R(pDecodedVideoSegment, pDestinations, m_nDestPitch);
    }
}


}//namespace UMC

#endif //(UMC_ENABLE_DVHD_VIDEO_DECODER)
